package demo.base;

import java.util.*;

public class ArrayListMap<K, V> implements
        Map<K, V> {

    private List<K> keyList = new ArrayList<K>();
    private List<V> valueList = new ArrayList<V>();

    @Override
    public int size() {
        return keyList.size();
    }

    @Override
    public boolean isEmpty() {
        return keyList.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return keyList.contains(key);
    }

    @Override
    public boolean containsValue(Object value) {
        return valueList.contains(value);
    }

    @Override
    public V get(Object key) {
        int index = keyList.indexOf(key);
        if(index == -1){
        	return null;
        }else {
        	return valueList.get(index);
        }
    }

    @Override
    public V put(K key, V value) {
        int index = keyList.indexOf(key);
        V oldValue = null;
        if (index == -1) {
            oldValue = null;
            keyList.add(key);
            valueList.add(value);
        } else {
            oldValue = valueList.get(index);
            valueList.set(index, value);
        }
        return oldValue;
    }

    @Override
    public V remove(Object key) {
        int index = keyList.indexOf(key);
        V oldValue = null;
        if (index != -1) {
            oldValue = valueList.get(index);
        }
        return oldValue;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public void putAll(Map<? extends K, ? extends V> m) {

        Set entrySet = m.entrySet();
        for (Object object : entrySet) {

            Entry<K, V> entry = (Entry<K, V>) object;
            put(entry.getKey(), entry.getValue());
        }

    }

    @Override
    public void clear() {
        keyList.clear();
        valueList.clear();

    }

    @Override
    public Set<K> keySet() {
        return new ListToSet<K>(keyList);
    }

    @Override
    public Collection<V> values() {
        return valueList;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public Set<Entry<K, V>> entrySet() {

        List<Entry<K, V>> list = new ArrayList<Entry<K, V>>();
        for (int i = 0; i < keyList.size(); i++) {

            Entry entry = new EntryImpl(keyList.get(i), valueList.get(i));

            list.add(entry);
        }

        return new ListToSet<Entry<K, V>>(list);
    }

    @Override
    public String toString() {
    	Iterator<Entry<K,V>> i = entrySet().iterator();
    	if (! i.hasNext())
    	    return "{}";

    	StringBuilder sb = new StringBuilder();
    	sb.append('{');
    	for (;;) {
    	    Entry<K,V> e = i.next();
    	    K key = e.getKey();
    	    V value = e.getValue();
    	    sb.append(key   == this ? "(this Map)" : key);
    	    sb.append('=');
    	    sb.append(value == this ? "(this Map)" : value);
    	    if (! i.hasNext())
    		return sb.append('}').toString();
    	    sb.append(", ");
    	}
        }
    
    static class EntryImpl<K, V> implements
            Entry<K, V> {

        private K key;
        private V value;

        public EntryImpl(K key, V value) {
            super();
            this.key = key;
            this.value = value;
        }

        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }

        @Override
        public V setValue(V value) {
            V oldValue = value;
            this.value = value;
            return oldValue;

        }

    }
    
    public class ListToSet<T> extends AbstractSet<T> {

        private List<T> list;

        public ListToSet(List<T> list) {
            super();
            this.list = list;
        }

        @Override
        public Iterator<T> iterator() {
            return list.iterator();
        }

        @Override
        public int size() {
            return list.size();
        }
        
    }


}
